﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace LFSRecord2.Model
{
    public class FileHistoryCollection : ICollection<FileHistoryInfo>, INotifyCollectionChanged
    {
        private const int MaxFileHistory = 10;
        private List<FileHistoryInfo> files = new List<FileHistoryInfo>();

        public event EventHandler<FileHistoryEventArgs> OpenFile;
        public event NotifyCollectionChangedEventHandler CollectionChanged;

        public int Count
        {
            get
            {
                return files.Count;
            }
        }

        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public FileHistoryCollection(StringCollection fileCollection)
        {
            if (fileCollection != null)
            {
                foreach (string file in fileCollection)
                {
                    FileHistoryInfo fileHistory = new FileHistoryInfo(file);
                    fileHistory.OpenFile += new EventHandler<FileHistoryEventArgs>(fileHistory_OpenFile);
                    files.Add(fileHistory);
                }
            }
        }

        public void Add(FileHistoryInfo fileHistory)
        {
            if (!files.Any(f => f.FileName == fileHistory.FileName))
            {
                files.Insert(0, fileHistory);
                fileHistory.OpenFile += new EventHandler<FileHistoryEventArgs>(fileHistory_OpenFile);

                OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                    NotifyCollectionChangedAction.Add,
                    fileHistory,
                    0));

                if (files.Count > MaxFileHistory)
                {
                    Remove(files.Last(), files.Count - 1);
                }
            }
        }

        public bool Remove(FileHistoryInfo fileHistory)
        {
            int index = files.IndexOf(fileHistory);
            if (index > -1)
            {
                Remove(fileHistory, index);

                return true;
            }

            return false;
        }

        private void Remove(FileHistoryInfo fileHistory, int index)
        {
            files.RemoveAt(index);
            fileHistory.OpenFile -= fileHistory_OpenFile;

            OnCollectionChanged(new NotifyCollectionChangedEventArgs(
                NotifyCollectionChangedAction.Remove,
                fileHistory,
                index));
        }

        public StringCollection ToStringCollection()
        {
            StringCollection stringCollection = new StringCollection();
            stringCollection.AddRange(files.Select(f => f.FileName).ToArray());
            return stringCollection;
        }

        private void fileHistory_OpenFile(object sender, FileHistoryEventArgs e)
        {
            OnOpenFile(e);

            if (e.IsOpened)
            {
                MoveFileToTop(e.File);
            }
        }

        private void MoveFileToTop(FileHistoryInfo fileHistory)
        {
            Remove(fileHistory);
            Add(fileHistory);
        }

        public void Clear()
        {
            files.Clear();
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }

        public bool Contains(FileHistoryInfo item)
        {
            return files.Contains(item);
        }

        public void CopyTo(FileHistoryInfo[] array, int arrayIndex)
        {
            files.CopyTo(array, arrayIndex);
        }

        public IEnumerator<FileHistoryInfo> GetEnumerator()
        {
            return files.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        protected virtual void OnOpenFile(FileHistoryEventArgs e)
        {
            EventHandler<FileHistoryEventArgs> temp = OpenFile;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            NotifyCollectionChangedEventHandler temp = CollectionChanged;
            if (temp != null)
            {
                temp(this, e);
            }
        }
    }
}